package com.sneakxy.cloudbase.platform.utils.web;

import java.util.function.Function;

import javax.servlet.http.HttpServletResponse;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 响应信息
 * @author 潜行的青衣
 * @see
 */
@Data
@ApiModel("响应信息")
public class Response<T> {

	@ApiModelProperty("是否成功")
	private boolean success;
	
	@ApiModelProperty("响应代码")
	private Integer code;
	
	@ApiModelProperty("响应信息")
	private String message;
	
	@ApiModelProperty("响应数据")
	private T data;

	private Response() {}
	
	public static <T> Response<T> ok(Integer code, String message, T data) {
		Response<T> response = new Response<>();
		response.setCode(code);
		response.setSuccess(true);
		response.setMessage(message);
		response.setData(data);
		return response;
	}
	
	public static <T> Response<T> ok() {
		return ok(HttpServletResponse.SC_OK, (String) null, (T) null);
	}
	
	public static <T> Response<T> ok(Integer code) {
		return ok(code, (String) null, (T) null);
	}
	
	public static <T> Response<T> ok(Integer code, String message) {
		return ok(code, message, (T) null);
	}
	
	public static <T> Response<T> ok(String message) {
		return ok(HttpServletResponse.SC_OK, message, (T) null);
	}
	
	public static <T> Response<T> ok(String message, T data) {
		return ok(HttpServletResponse.SC_OK, message, data);
	}
	
	public static <T> Response<T> ok(T data) {
		return ok(HttpServletResponse.SC_OK, null, data);
	}
	
	public static <T> Response<T> ok(Integer code, T data) {
		return ok(code, null, data);
	}
	
	public static <E, T> Response<T> ok(Integer code, String message, E entity, Function<E, T> function) {
		return ok(code, message, entity != null ? function.apply(entity) : (T) null);
	}
	
	public static <E, T> Response<T> ok(E entity, Function<E, T> function) {
		return ok(HttpServletResponse.SC_OK, null, entity, function);
	}
	
	public static <E, T> Response<T> ok(Integer code, E entity, Function<E, T> function) {
		return ok(code, null, entity, function);
	}
	
	public static <T> Response<T> fail(Integer code, String message, T data) {
		Response<T> response = new Response<>();
		response.setCode(code);
		response.setSuccess(false);
		response.setMessage(message);
		response.setData(data);
		return response;
	}
	
	public static <T> Response<T> fail() {
		return fail(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null, null);
	}
	
	public static <T> Response<T> fail(Integer code) {
		return fail(code, null, null);
	}
	
	public static <T> Response<T> fail(Integer code, String message) {
		return fail(code, message, null);
	}
	
	public static <T> Response<T> fail(String message) {
		return fail(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message, null);
	}
	
	public static <T> Response<T> fail(String message, T data) {
		return fail(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message, data);
	}
	
	public static <T> Response<T> fail(Integer code, T data) {
		return fail(code, null, data);
	}
	
	public boolean isSuccess() {
		return success;
	}

}
